package com.netx.generics.basic;
import com.netx.generics.util.Tools;


public abstract class AbstractLogger implements Logger {

	private LEVEL _level;

	protected AbstractLogger() {
		_level = LEVEL.INFO;
	}

	public LEVEL getLevel() {
		return _level;
	}

	public void setLevel(LEVEL level) {
		Checker.checkNull(level, "level");
		_level = level;
	}

	public void info(String message) {
		if(_level == LEVEL.INFO) {
			try {
				output(_getPlace(), LEVEL.INFO, message, null);
			}
			catch(Throwable t) {
				Tools.handleCriticalError(t);
			}
		}
	}
	
	public void warning(String message) {
		warning(message, null);
	}

	public void warning(String message, Throwable t) {
		if(_level==LEVEL.INFO || _level==LEVEL.WARNING) {
			try {
				output(_getPlace(), LEVEL.WARNING, message, t);
			}
			catch(Throwable t2) {
				Tools.handleCriticalError(t2);
			}
		}
	}

	public void error(String message, Throwable t) {
		if(_level != LEVEL.NONE) {
			try {
				output(_getPlace(), LEVEL.ERROR, message, t);
			}
			catch(Throwable t2) {
				Tools.handleCriticalError(t2);
			}
		}
	}

	public void error(Throwable t) {
		error(null, t);
	}
	
	protected abstract void output(StackTraceElement place, LEVEL type, String message, Throwable t) throws Throwable;

	private StackTraceElement _getPlace() {
		Exception e = new Exception();
		StackTraceElement[] elems = e.getStackTrace();
		// Make sure the StackTrace place is immediately before AbstractLogger:
		for(int i=2; i<elems.length; i++) {
			if(elems[i].toString().indexOf("AbstractLogger") == -1) {
				return elems[i];
			}
		}
		throw new IntegrityException(elems);
	}

}
